<!-- 表格模版组件，无分页 -->
<template>
  <a-table
    v-model:expandedRowKeys="expandedRowKeys"
    :dataSource="tableData"
    :columns="processedColumns"
    :rowKey="rowKey"
    :loading="isLoading"
    :pagination="false"
    :scroll="{ x: 'max-content' }"
    bordered
    :expandAllRows="expandAllRows"
    class="table-template"
  />
</template>
<script setup lang="tsx">
  import { ref, watch, computed } from 'vue';
  import dayjs from 'dayjs';
  import { type CustomTableColumnType } from '@/types/table'; //扩展 TableColumnType 定义
  import FlexButtons from '@/components/common/button/flex-buttons.vue'; //表格操作按钮模板
  import DropdownButtons from '@/components/common/button/dropdown-buttons.vue'; //表格操作按钮模板
  import { bizApi } from '@/api/biz';
  import { Flex, type TableColumnType, type TableProps } from 'ant-design-vue';
  import { isFunction } from 'lodash-es';

  /* 定义组件对外暴露接口 props */
  interface Props {
    columns: CustomTableColumnType[]; //表格列配置
  }
  /* 配置 props 默认值 */
  const props = defineProps<Props>();

  const rowKey = ref('module_id'); //临时，服务端会统一返回 id 字段
  const expandAllRows = ref(true);
  const isLoading = ref(false); //表格加载状态 默认为false
  const tableData = ref<TableProps['dataSource']>([]); //表格数据
  const postParams = ref({}); //列表请求参数，调用组件传入
  const postAction = ref(''); //列表请求方法，调用组件传入
  /* 数据服务请求（访问服务端接口获取数据） */
  async function getTableData(action: string, params: Record<string, any>, returnFlag?: boolean) {
    isLoading.value = true;
    let result = [];
    try {
      postParams.value = params; //赋值给响应变量
      postAction.value = action; //赋值给响应变量

      result = await bizApi.httpList(postAction.value, postParams.value);
      tableData.value = result || []; //列表数据
    } catch (error) {
      tableData.value = [];
      isLoading.value = false;
      return Promise.reject(error);
    }
    isLoading.value = false;
    if (returnFlag) {
      return result;
    }
  }

  /* 暴露接口供调用组件(父组件)使用 */
  defineExpose({
    getTableData,
  });

  /* 按钮点击事件，执行外部传入的 onClick 函数（闭包） */
  const btnItemClick = (btn: any, record: any, e?: Event) => {
    // 通用逻辑：权限校验
    console.log('btn.permission', btn.permission);

    e?.stopPropagation(); // 通用逻辑：阻止事件冒泡
    try {
      // 执行按钮原始点击回调
      if (typeof btn.onClick === 'function') {
        btn.onClick(record, e);
      }
    } catch (error) {
      // 捕获，未处理全局异常
      console.error(`【${btn.text}】操作执行失败：`, error);
    }
  };
  /* 枚举值映射为文本 */
  const mapEnumToText = (text: any, map: Record<any, string>) => {
    return map[text] || text;
  };

  /* 父组件定义的「列特征匹配规则」：根据列的特征自动应用默认属性 */
  const columnRules: { matcher: (col: CustomTableColumnType<any>) => boolean | undefined; defaults: TableColumnType }[] = [
    /* 规则：匹配 options 属性不为空（自定义属性） 不为空（存在）的列,存在则将 枚举值映射为文本值 */
    {
      matcher: (col: CustomTableColumnType<any>) => !!col.options, // 关键：判断 options 是否存在
      defaults: {
        width: 80, // 预设宽度（可根据需求调整）
        ellipsis: true, // 预设省略（避免文本溢出）
        align: 'center', // 预设居中（类型列常用）
        /* 枚举渲染：直接用列配置的 options，无默认值 */
        customRender: ({ text, column: _column }) => {
          const column = _column as CustomTableColumnType;
          return mapEnumToText(text, column.options || {}); // 使用配置列的 options，无默认映射（空则返回原始值）
        },
      },
    },
    /* 规则：毫秒级时间戳转换规则 */
    {
      // 匹配标题含「时间」「日期」的列
      matcher: (col: CustomTableColumnType<any>) => {
        return col.title?.toString().includes('时间') || col.title?.toString().includes('日期');
      },
      defaults: {
        width: 180,
        align: 'center' as CustomTableColumnType['align'],
        ellipsis: true,
        // 专门处理毫秒级时间戳（13位）
        customRender: ({ text }) => {
          if (!text) return '-'; // 空值显示占位符

          // 转换为数字类型
          const timestamp = typeof text === 'string' ? Number(text) : text;
          if (isNaN(timestamp)) return text; // 非数字不转换

          // 处理时间戳（区分10位秒级和13位毫秒级）
          let msTimestamp: number;
          const timestampStr = timestamp.toString();

          if (timestampStr.length === 10) {
            // 10位：秒级时间戳 → 转为毫秒级
            msTimestamp = timestamp * 1000;
          } else if (timestampStr.length === 13) {
            // 13位：直接使用毫秒级时间戳
            msTimestamp = timestamp;
          } else {
            // 其他长度：视为无效格式
            return `无效时间戳: ${text}`;
          }

          // 格式化毫秒级时间戳（使用dayjs）
          return dayjs(msTimestamp).format('YYYY-MM-DD HH:mm:ss');
        },
      },
    },
    /* 规则：标题包含「排序」的列（如“菜单排序”“用户排序”）*/
    {
      matcher: (col: CustomTableColumnType<any>) => col.title?.toString().includes('排序'),
      defaults: {
        width: 30,
        align: 'center' as CustomTableColumnType['align'],
        ellipsis: true,
      },
    },
    /* 规则：简化按钮传入 */
    {
      matcher: (col: CustomTableColumnType<any>) => col.dataIndex === 'action',
      defaults: {
        title: '操作',
        fixed: 'right' as const,
        width: 120,
        align: 'center' as CustomTableColumnType['align'],
        ellipsis: false,
        /* 预设操作列渲染逻辑：自动渲染 TableActions，读取 buttons 数组 */
        customRender: ({ record, column: _column }) => {
          const column = _column as CustomTableColumnType;
          const colBUttons = (isFunction(column.buttons) ? column.buttons(record) : column.buttons) || [];
          /* 从列配置中获取 buttons 数组（使用侧传入的按钮配置） */
          const actionButtons = colBUttons.filter((btn) => !btn.more);
          const moreActionButtons = colBUttons.filter((btn) => btn.more);
          const buttons: any[] = actionButtons.map((btn) => ({
            ...btn,
            /* 若按钮的 onClick 依赖 record，自动注入 record（可选，增强灵活性） */
            onClick: (e?: Event) => btnItemClick(btn, record, e),
          }));
          const moreButtons: any[] = moreActionButtons.map((btn) => ({
            ...btn,
            /* 若按钮的 onClick 依赖 record，自动注入 record（可选，增强灵活性） */
            onClick: (e?: Event) => btnItemClick(btn, record, e),
          }));
          /* 渲染 TableActions 组件，传递 buttons 和 record（供点击事件使用） */
          return moreButtons.length ? (
            <Flex gap={8} align='center'>
              <FlexButtons buttons={buttons}></FlexButtons>
              <DropdownButtons buttons={moreButtons}></DropdownButtons>
            </Flex>
          ) : (
            <FlexButtons buttons={buttons}></FlexButtons>
          );
        },
      },
    },
    // 规则4：所有列的默认配置（优先级最低，仅当以上规则都不匹配时生效）
    {
      matcher: () => true, // 始终返回true，匹配所有列
      defaults: {
        ellipsis: true, // 所有列默认开启省略
        customHeaderCell() {
          return { style: { textAlign: 'center' } };
        },
      },
    },
  ];

  /* 处理列配置：根据规则自动添加默认属性（子组件配置优先级更高） */
  const processedColumns = computed<CustomTableColumnType<any>[]>(() => {
    return props.columns.map((col) => {
      const matchedRule = columnRules.find((rule) => rule.matcher(col)); // 找到匹配的规则
      if (matchedRule) {
        // 合并：子组件配置覆盖父组件默认值
        return { ...matchedRule.defaults, ...col };
      }
      return col; // 无匹配规则则返回原始配置
    });
  });

  /* expandAllRows 为 true 时将表单所有节点展开 */
  const expandedRowKeys = ref<any[]>([]);
  watch(
    () => [expandAllRows.value, tableData.value],
    () => {
      if (expandAllRows.value) {
        const safeData = tableData.value || [];
        expandedRowKeys.value = safeData.flatMap((first) => [
          first[rowKey.value], // 一级节点
          ...(first.children || []).flatMap((second: any) => [
            second[rowKey.value], // 二级节点
            ...(second.children || []).map((third: any) => third[rowKey.value]), // 三级节点
          ]),
        ]);
      }
    }
  );
</script>
<style lang="less" scoped>
  :deep(th.column-money) {
    text-align: center !important;
  }
</style>
